<script>
import CustomEase from "gsap/CustomEase";
import {gsap} from "gsap";

export default {
    name: "GSAP3DCarousel",
    mounted() {
        CustomEase.create('cubic', '0.83, 0, 0.17, 1')
        let isAnimating = false

        function splitTextIntoSpans(selector) {
            let elements = document.querySelectorAll(selector)
            elements.forEach(element => {
                let text = element.innerText
                element.innerHTML = text.split('').map(char => {
                    return `<span>${char === '' ? '&nbsp;&nbsp' : char}</span>`
                }).join('')
            })
        }

        function initializeCards() {
            let cards = Array.from(document.querySelectorAll('.card'))
            gsap.to(cards, {
                y: (i) => -15 + 15 * i + '%',
                z: (i) => 15 * i,
                duration: 1,
                ease: 'cubic',
                stagger: -0.1
            })
        }

        document.addEventListener('DOMContentLoaded', function () {
            splitTextIntoSpans('.copy h1')
            initializeCards()

            gsap.set('h1 span', {y: -200})
            gsap.set('.slider .card:last-child h1 span', {y: 0})
        })

        document.addEventListener('click', function () {
            if (isAnimating) return

            isAnimating = true

            let slider = document.querySelector('.slider')
            let cards = Array.from(slider.querySelectorAll('.card'))
            let lastCard = cards.pop()
            let nextCard = cards[cards.length - 1]

            gsap.to(lastCard.querySelectorAll('h1 span'), {
                y: 200,
                duration: 0.75,
                ease: 'cubic'
            })

            gsap.to(lastCard, {
                y: '+=150%',
                duration: 0.75,
                ease: 'cubic',
                onComplete: () => {
                    slider.prepend(lastCard)
                    initializeCards()
                    gsap.set(lastCard.querySelectorAll('h1 span'), {y: -200})

                    setTimeout(() => {
                        isAnimating = false
                    }, 1000)
                }
            })

            gsap.to(nextCard.querySelectorAll('h1 span'), {
                y: 0,
                duration: 1,
                ease: 'cubic',
                stagger: 0.05
            })
        })
    }
}
</script>

<template>
    <div>
        <nav>
            <div class="logo">
                <a href="#">Noir Wood</a>
            </div>
            <div class="pages">
                <a href="#">Films</a>
                <a href="#">Production</a>
                <a href="#">Info</a>
                <a href="#">Contract</a>
            </div>
            <div class="shop">
                <a href="#">Search</a>
                <a href="#">Account</a>
                <a href="#">Cart</a>
            </div>
        </nav>
        <footer>
            <p>GSAP3DCarousel</p>
            <p>2024 / 2025</p>
        </footer>

        <div class="container">
            <div class="slider">
                <div class="card">
                    <img alt="" src="../assets/1.png">
                    <div class="copy">
                        <h1>Lorem1</h1>
                    </div>
                </div>
                <div class="card">
                    <img alt="" src="../assets/2.png">
                    <div class="copy">
                        <h1>Lorem2</h1>
                    </div>
                </div>
                <div class="card">
                    <img alt="" src="../assets/3.png">
                    <div class="copy">
                        <h1>Lorem3</h1>
                    </div>
                </div>
                <div class="card">
                    <img alt="" src="../assets/4.png">
                    <div class="copy">
                        <h1>Lorem4</h1>
                    </div>
                </div>
                <div class="card">
                    <img alt="" src="../assets/5.png">
                    <div class="copy">
                        <h1>Lorem5</h1>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<style scoped lang="less">
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

p, a {
    text-decoration: none;
    font-weight: 500;
    font-size: 14px;
    color: #000;
}

h1 {
    position: relative;
    text-align: center;
    font-size: 6vw;
    font-weight: 300;
    letter-spacing: -0.05em;
    text-transform: uppercase;
    color: #dfe1c8;

    span {
        position: relative;
        display: inline-block;
    }
}

nav {
    position: absolute;
    top: 0;
    width: 100%;
    padding: 2em;
    display: flex;
    align-items: center;
    z-index: 2;

    div {
        flex: 1;
    }

    .pages {
        display: flex;
        justify-content: center;
        align-items: center;
        gap: 0.5em;
    }

    .shop {
        display: flex;
        justify-content: flex-end;
        align-items: center;
        gap: 1em;
    }
}

footer {
    position: absolute;
    bottom: 0;
    width: 100%;
    padding: 2em;
    display: flex;
    justify-content: space-between;
    align-items: center;
    z-index: 2;
}

.container {
    position: relative;
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    background: #dfe1c8;

    .slider {
        position: absolute;
        top: 15vh;
        width: 100vw;
        height: 100vh;
        overflow: hidden;
        perspective: 200px;
        perspective-origin: 50% 100%;

        .card {
            position: absolute;
            top: 50%;
            left: 50%;
            width: 50%;
            height: 500px;
            border-radius: 10px;
            overflow: hidden;
            transform: translate3d(-50%, -50%, 0);
            background: #000;

            img {
                position: absolute;
                opacity: 0.75;
            }

            .copy {
                position: absolute;
                top: 40%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 100%;
                clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
            }
        }
    }
}
</style>